/**
 * Author: Wang Haitao
 * Date: 2024-xx-xx
 * Description: 这个文件关于INA226 INA228的大部分驱动描述
 * Code Copy：拷贝代码，请加上作者信息。
 */
#ifndef __INA22X_DRIVER_H__
#define __INA22X_DRIVER_H__

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "../../BSP/I2C_BSP/i2c_bus.h"
#include "../../Tool/Soft_I2C/soft_i2c_bus.h"
#include "INA22x_Alert_IO.h"


#define    INA22x_Max_Current_mA            5200.0f
#define    INA22x_Max_Voltage_mV            85000.0f

#define    INA22x_Sampling_Res_1Milliohm   1
#define    INA22x_Sampling_Res_2Milliohm   2
#define    INA22x_Sampling_Res_5Milliohm   5
#define    INA22x_Sampling_Res_8Milliohm   8
#define    INA22x_Sampling_Res_10Milliohm  10
#define    INA22x_Sampling_Res_16Milliohm  16
#define    INA22x_Sampling_Res_20Milliohm  20
#define    INA22x_Sampling_Res_30Milliohm  30


typedef enum
{
    INA22x_7Bit_Addr1  = 0x40,
    INA22x_7Bit_Addr2  = 0x41,
    INA22x_7Bit_Addr3  = 0x42,
    INA22x_7Bit_Addr4  = 0x43,
    INA22x_7Bit_Addr5  = 0x44,
    INA22x_7Bit_Addr6  = 0x45,
    INA22x_7Bit_Addr7  = 0x46,
    INA22x_7Bit_Addr8  = 0x47,
    INA22x_7Bit_Addr9  = 0x48,
    INA22x_7Bit_Addr10 = 0x49,
    INA22x_7Bit_Addr11 = 0x4A,
    INA22x_7Bit_Addr12 = 0x4B,
    INA22x_7Bit_Addr13 = 0x4C,
    INA22x_7Bit_Addr14 = 0x4D,
    INA22x_7Bit_Addr15 = 0x4E,
    INA22x_7Bit_Addr16 = 0x4F,
}WHT_INA22x_Addr_enum;

typedef enum
{
	CNV_Time_5ms = 0,
	CNV_Time_9ms,
	CNV_Time_17ms,
	CNV_Time_19ms,
}WHT_INA22x_CNV_Time_enum;

typedef enum
{
	INA226_Stop_Mode = 0,         //停止转换
	INA226_I_Trigger_Mode,        //触发电流
	INA226_V_Trigger_Mode,        //触发电压
	INA226_V_I_Trigger_Mode,      //触发电压和电流
	INA226_I_Continuous_Mode = 5, //连续电流
	INA226_V_Continuous_Mode,     //连续电压
	INA226_V_I_Continuous_Mode,   //连续电压和电流
}WHT_INA226_Mode_enum;

typedef enum
{
	INA228_Stop_Mode = 0,         //停止转换
	INA228_V_Trigger_Mode,        //触发电压
	INA228_I_Trigger_Mode,        //触发电流
	INA228_V_I_Trigger_Mode,      //触发电压和电流
	INA228_T_Trigger_Mode,        //触发温度
	INA228_V_T_Trigger_Mode,      //触发电压和温度
	INA228_I_T_Trigger_Mode,      //触发电流和温度
	INA228_V_I_T_Trigger_Mode,    //触发电压和电流和温度
	INA228_V_Continuous_Mode = 9, //连续电压
	INA228_I_Continuous_Mode,     //连续电流
	INA228_V_I_Continuous_Mode,   //连续电压和电流
	INA228_T_Continuous_Mode,     //连续温度
	INA228_V_T_Continuous_Mode,   //连续电压和温度
	INA228_I_T_Continuous_Mode,   //连续电流和温度
	INA228_V_I_T_Continuous_Mode, //连续电压和电流和温度
}WHT_INA228_Mode_enum;

typedef struct
{
	float Shunt_Voltage_uV;//分流器电压
	float Voltage_mV;      //电压
	float Current_mA;      //电流
	float Power_mW;        //功率
}WHT_INA226_Value_t;

typedef struct
{
	float Shunt_Voltage_uV;//分流器电压
	float Voltage_mV;      //电压
	float Current_mA;      //电流
	float Power_mW;        //功率
	float Temp_mC;         //温度
}WHT_INA228_Value_t;

typedef struct
{
	//总配置
	WHT_INA22x_Addr_enum Addr;
	WHT_INA226_Mode_enum Mode;
	WHT_INA22x_CNV_Time_enum Convert_Time;
	//警报配置
	uint8_t Alert_SHNTOL : 1; //分流器电压上限警报使能开关
	uint8_t Alert_SHNTUL : 1; //分流器电压下限警报使能开关
	uint8_t Alert_BUSOL  : 1; //电压上限警报使能开关
	uint8_t Alert_BUSUL  : 1; //电压下限警报使能开关
	uint8_t Alert_POL    : 1; //功率上限警报使能开关
	uint8_t Alert_CNVR   : 1; //0:禁用警报引脚转换完成    1:启动警报引脚转换完成
	uint8_t Alert_APOL   : 1; //0:警报引脚低电平有效      1:警报引脚高电平有效
	uint8_t Alert_ALATCH : 1; //0:标志和警报引脚自动释放  1:标志和警报引脚锁存，读取警报寄存器自动清除
	//警报门槛值
	uint16_t Alert_Voltage_Hig;
	uint16_t Alert_Voltage_Low;
	uint16_t Alert_Current_Hig;
	uint16_t Alert_Current_Low;
	uint16_t Alert_Power_Hig;
	//校准参数
	uint16_t Calibration_Shunt_Gain_Val;
	float Calibration_VBus_Gain_Val;
	//电流采样电阻
	float Sampling_Res_Milliohm;
}WHT_INA226_Config_t;

typedef struct
{
	//总配置
	WHT_INA22x_Addr_enum Addr;
	WHT_INA228_Mode_enum Mode;
	WHT_INA22x_CNV_Time_enum Convert_Time;
	uint8_t Config_RSTACC;    //电量和电荷清零开关
	uint8_t Config_CONVDLY_mS;//延迟启动ADC转换
	uint8_t Config_TEMPCOMP;  //禁用与启用分流器温度补偿开关
	uint8_t Config_ADCRANGE;  //分流器满量程选择0：±163.84mV 1：±40.96mV
	//警报配置
	uint8_t Alert_ALATCH   : 1; //0:标志和警报引脚自动释放  1:标志和警报引脚锁存，读取警报寄存器自动清除
	uint8_t Alert_CNVR     : 1; //0:禁用警报引脚转换完成    1:启动警报引脚转换完成
	uint8_t Alert_SLOWALERT: 1; //0:每次采集比较警报门槛值  1:平均值后比较警报门槛值
	uint8_t Alert_APOL     : 1; //0:警报引脚低电平有效      1:警报引脚高电平有效
	uint8_t Alert_TMPOL    : 1; //温度上限警报使能开关
	uint8_t Alert_SHNTOL   : 1; //分流器电压上限警报使能开关
	uint8_t Alert_SHNTUL   : 1; //分流器电压下限警报使能开关
	uint8_t Alert_BUSOL    : 1; //电压上限警报使能开关
	uint8_t Alert_BUSUL    : 1; //电压下限警报使能开关
	uint8_t Alert_POL      : 1; //功率上限警报使能开关
	uint8_t Alert          : 6;
	//警报门槛值
	uint16_t Alert_Voltage_Hig;
	uint16_t Alert_Voltage_Low;
	uint16_t Alert_Current_Hig;
	uint16_t Alert_Current_Low;
	uint16_t Alert_Temp_Hig;
	uint16_t Alert_Power_Hig;
	//校准参数
	uint16_t Calibration_Shunt_Gain_Val;
	float Calibration_VBus_Gain_Val;
	//电流采样电阻
	float Sampling_Res_Milliohm;
}WHT_INA228_Config_t;

typedef struct
{
	WHT_INA226_Config_t Config;
	WHT_INA226_Value_t* Result;
}WHT_INA226_Info_t;

typedef struct
{
	WHT_INA228_Config_t Config;
	WHT_INA228_Value_t* Result;
}WHT_INA228_Info_t;

typedef struct
{
	void (*WHT_Init)(WHT_INA226_Info_t* info);
	void (*WHT_Set_Work_Mode)(WHT_INA226_Info_t* info);
	void (*WHT_Set_Calibration_Shunt_Gain)(WHT_INA226_Info_t* info);
	void (*WHT_Set_Convert_Time)(WHT_INA226_Info_t* info);
	void (*WHT_Set_Alert_Func)(WHT_INA226_Info_t* info);
	void (*WHT_Set_Alert_Value)(WHT_INA226_Info_t* info);
	void (*WHT_Get_Voltage)(WHT_INA226_Info_t* info);
	void (*WHT_Get_Shunt_Voltage)(WHT_INA226_Info_t* info);
	void (*WHT_Get_Current)(WHT_INA226_Info_t* info);
	void (*WHT_Get_Power)(WHT_INA226_Info_t* info);
	uint16_t (*WHT_Get_Alert_Flag)(WHT_INA226_Info_t* info);
	uint16_t (*WHT_Get_Default_Calibration_Shunt_Gain)(WHT_INA226_Info_t* info);
	uint8_t (*WHT_Scan_I2C_Slave_Count)(void);
}WHT_INA226_Driver_t;

typedef struct
{
	void (*WHT_Init)(WHT_INA228_Info_t* info);
	void (*WHT_Set_Work_Mode)(WHT_INA228_Info_t* info);
	void (*WHT_Set_Calibration_Shunt_Gain)(WHT_INA228_Info_t* info);
	void (*WHT_Set_Convert_Time)(WHT_INA228_Info_t* info);
	void (*WHT_Set_Alert_Func)(WHT_INA228_Info_t* info);
	void (*WHT_Set_Alert_Value)(WHT_INA228_Info_t* info);
	void (*WHT_Get_Voltage)(WHT_INA228_Info_t* info);
	void (*WHT_Get_Shunt_Voltage)(WHT_INA228_Info_t* info);
	void (*WHT_Get_Current)(WHT_INA228_Info_t* info);
	void (*WHT_Get_Power)(WHT_INA228_Info_t* info);
	void (*WHT_Get_Energy)(WHT_INA228_Info_t* info);
	void (*WHT_Get_Charge)(WHT_INA228_Info_t* info);
	uint16_t (*WHT_Get_Alert_Flag)(WHT_INA228_Info_t* info);
	uint16_t (*WHT_Get_Default_Calibration_Shunt_Gain)(WHT_INA228_Info_t* info);
	uint8_t (*WHT_Scan_I2C_Slave_Count)(void);
}WHT_INA228_Driver_t;

extern const WHT_INA226_Driver_t WHT_INA226_Driver;
extern const WHT_INA228_Driver_t WHT_INA228_Driver;

#endif
